home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / compiler / mips / array.lisp < prev    next >
Encoding:
Text File  |  1991-11-09  |  14.6 KB  |  455 lines

  1. ;;; -*- Package: MIPS -*-
  2. ;;;
  3. ;;; **********************************************************************
  4. ;;; This code was written as part of the CMU Common Lisp project at
  5. ;;; Carnegie Mellon University, and has been placed in the public domain.
  6. ;;; If you want to use this code or any part of CMU Common Lisp, please contact
  7. ;;; Scott Fahlman or slisp-group@cs.cmu.edu.
  8. ;;;
  9. (ext:file-comment
  10.   "$Header: array.lisp,v 1.33 91/11/09 02:37:36 wlott Exp $")
  11. ;;;
  12. ;;; **********************************************************************
  13. ;;;
  14. ;;; $Header: array.lisp,v 1.33 91/11/09 02:37:36 wlott Exp $
  15. ;;;
  16. ;;;    This file contains the MIPS definitions for array operations.
  17. ;;;
  18. ;;; Written by William Lott
  19. ;;;
  20. (in-package "MIPS")
  21.  
  22.  
  23. ;;;; Allocator for the array header.
  24.  
  25. (define-vop (make-array-header)
  26.   (:policy :fast-safe)
  27.   (:translate make-array-header)
  28.   (:args (type :scs (any-reg))
  29.      (rank :scs (any-reg)))
  30.   (:arg-types positive-fixnum positive-fixnum)
  31.   (:temporary (:scs (descriptor-reg) :to (:result 0) :target result) header)
  32.   (:temporary (:scs (non-descriptor-reg) :type random) ndescr)
  33.   (:results (result :scs (descriptor-reg)))
  34.   (:generator 25
  35.     (pseudo-atomic (ndescr)
  36.       (inst addu header alloc-tn vm:other-pointer-type)
  37.       (inst addu alloc-tn
  38.         (+ (* vm:array-dimensions-offset vm:word-bytes)
  39.            vm:lowtag-mask))
  40.       (inst addu alloc-tn rank)
  41.       (inst li ndescr (lognot vm:lowtag-mask))
  42.       (inst and alloc-tn ndescr)
  43.       (inst addu ndescr rank (fixnum (1- vm:array-dimensions-offset)))
  44.       (inst sll ndescr ndescr vm:type-bits)
  45.       (inst or ndescr ndescr type)
  46.       (inst srl ndescr ndescr 2)
  47.       (storew ndescr header 0 vm:other-pointer-type))
  48.     (move result header)))
  49.  
  50.  
  51. ;;;; Additional accessors and setters for the array header.
  52.  
  53. (defknown lisp::%array-dimension (t fixnum) fixnum
  54.   (flushable))
  55. (defknown lisp::%set-array-dimension (t fixnum fixnum) fixnum
  56.   ())
  57.  
  58. (define-vop (%array-dimension word-index-ref)
  59.   (:translate lisp::%array-dimension)
  60.   (:policy :fast-safe)
  61.   (:variant vm:array-dimensions-offset vm:other-pointer-type))
  62.  
  63. (define-vop (%set-array-dimension word-index-set)
  64.   (:translate lisp::%set-array-dimension)
  65.   (:policy :fast-safe)
  66.   (:variant vm:array-dimensions-offset vm:other-pointer-type))
  67.  
  68.  
  69.  
  70. (defknown lisp::%array-rank (t) fixnum (flushable))
  71.  
  72. (define-vop (array-rank-vop)
  73.   (:translate lisp::%array-rank)
  74.   (:policy :fast-safe)
  75.   (:args (x :scs (descriptor-reg)))
  76.   (:temporary (:scs (non-descriptor-reg) :type random) temp)
  77.   (:results (res :scs (any-reg descriptor-reg)))
  78.   (:generator 6
  79.     (loadw temp x 0 vm:other-pointer-type)
  80.     (inst sra temp vm:type-bits)
  81.     (inst subu temp (1- vm:array-dimensions-offset))
  82.     (inst sll res temp 2)))
  83.  
  84.  
  85.  
  86. ;;;; Bounds checking routine.
  87.  
  88.  
  89. (define-vop (check-bound)
  90.   (:translate %check-bound)
  91.   (:policy :fast-safe)
  92.   (:args (array :scs (descriptor-reg))
  93.      (bound :scs (any-reg descriptor-reg))
  94.      (index :scs (any-reg descriptor-reg) :target result))
  95.   (:results (result :scs (any-reg descriptor-reg)))
  96.   (:temporary (:scs (non-descriptor-reg) :type random) temp)
  97.   (:vop-var vop)
  98.   (:save-p :compute-only)
  99.   (:generator 5
  100.     (let ((error (generate-error-code vop invalid-array-index-error
  101.                       array bound index)))
  102.       (inst sltu temp index bound)
  103.       (inst beq temp zero-tn error)
  104.       (inst nop)
  105.       (move result index))))
  106.  
  107.  
  108.  
  109. ;;;; Accessors/Setters
  110.  
  111. ;;; Variants built on top of word-index-ref, etc.  I.e. those vectors whos
  112. ;;; elements are represented in integer registers and are built out of
  113. ;;; 8, 16, or 32 bit elements.
  114.  
  115. (defmacro def-data-vector-frobs (type variant element-type &rest scs)
  116.   `(progn
  117.      (define-vop (,(intern (concatenate 'simple-string
  118.                     "DATA-VECTOR-REF/"
  119.                     (string type)))
  120.           ,(intern (concatenate 'simple-string
  121.                     (string variant)
  122.                     "-REF")))
  123.        (:note "inline array access")
  124.        (:variant vm:vector-data-offset vm:other-pointer-type)
  125.        (:translate data-vector-ref)
  126.        (:arg-types ,type positive-fixnum)
  127.        (:results (value :scs ,scs))
  128.        (:result-types ,element-type))
  129.      (define-vop (,(intern (concatenate 'simple-string
  130.                     "DATA-VECTOR-SET/"
  131.                     (string type)))
  132.           ,(intern (concatenate 'simple-string
  133.                     (string variant)
  134.                     "-SET")))
  135.        (:note "inline array store")
  136.        (:variant vm:vector-data-offset vm:other-pointer-type)
  137.        (:translate data-vector-set)
  138.        (:arg-types ,type positive-fixnum ,element-type)
  139.        (:args (object :scs (descriptor-reg))
  140.           (index :scs (any-reg zero immediate unsigned-immediate))
  141.           (value :scs ,scs))
  142.        (:results (result :scs ,scs))
  143.        (:result-types ,element-type))))
  144.  
  145. (def-data-vector-frobs simple-string byte-index
  146.   base-char base-char-reg)
  147. (def-data-vector-frobs simple-vector word-index
  148.   * descriptor-reg any-reg)
  149.  
  150. (def-data-vector-frobs simple-array-unsigned-byte-8 byte-index
  151.   positive-fixnum unsigned-reg)
  152. (def-data-vector-frobs simple-array-unsigned-byte-16 halfword-index
  153.   positive-fixnum unsigned-reg)
  154. (def-data-vector-frobs simple-array-unsigned-byte-32 word-index
  155.   unsigned-num unsigned-reg)
  156.  
  157.  
  158. ;;; Integer vectors whos elements are smaller than a byte.  I.e. bit, 2-bit,
  159. ;;; and 4-bit vectors.
  160. ;;; 
  161.  
  162. (defmacro def-small-data-vector-frobs (type bits)
  163.   (let* ((elements-per-word (floor vm:word-bits bits))
  164.      (bit-shift (1- (integer-length elements-per-word))))
  165.     `(progn
  166.        (define-vop (,(symbolicate 'data-vector-ref/ type))
  167.      (:note "inline array access")
  168.      (:translate data-vector-ref)
  169.      (:policy :fast-safe)
  170.      (:args (object :scs (descriptor-reg))
  171.         (index :scs (unsigned-reg)))
  172.      (:arg-types ,type positive-fixnum)
  173.      (:results (value :scs (any-reg)))
  174.      (:result-types positive-fixnum)
  175.      (:temporary (:scs (interior-reg)) lip)
  176.      (:temporary (:scs (non-descriptor-reg) :to (:result 0)) temp result)
  177.      (:generator 20
  178.        (inst srl temp index ,bit-shift)
  179.        (inst sll temp 2)
  180.        (inst addu lip object temp)
  181.        (inst lw result lip
  182.          (- (* vm:vector-data-offset vm:word-bytes)
  183.             vm:other-pointer-type))
  184.        (inst and temp index ,(1- elements-per-word))
  185.        ,@(when (eq (backend-byte-order *backend*) :big-endian)
  186.            `((inst xor temp ,(1- elements-per-word))))
  187.        ,@(unless (= bits 1)
  188.            `((inst sll temp ,(1- (integer-length bits)))))
  189.        (inst srl result temp)
  190.        (inst and result ,(1- (ash 1 bits)))
  191.        (inst sll value result 2)))
  192.        (define-vop (,(symbolicate 'data-vector-ref-c/ type))
  193.      (:translate data-vector-ref)
  194.      (:policy :fast-safe)
  195.      (:args (object :scs (descriptor-reg)))
  196.      (:arg-types ,type
  197.              (:constant
  198.               (integer 0
  199.                    ,(1- (* (1+ (- (floor (+ #x7fff
  200.                             vm:other-pointer-type)
  201.                              vm:word-bytes)
  202.                           vm:vector-data-offset))
  203.                        elements-per-word)))))
  204.      (:info index)
  205.      (:results (result :scs (unsigned-reg)))
  206.      (:result-types positive-fixnum)
  207.      (:generator 15
  208.        (multiple-value-bind (word extra) (floor index ,elements-per-word)
  209.          ,@(when (eq (backend-byte-order *backend*) :big-endian)
  210.          `((setf extra (logxor extra (1- ,elements-per-word)))))
  211.          (loadw result object (+ word vm:vector-data-offset) 
  212.             vm:other-pointer-type)
  213.          (unless (zerop extra)
  214.            (inst srl result (* extra ,bits)))
  215.          (unless (= extra ,(1- elements-per-word))
  216.            (inst and result ,(1- (ash 1 bits)))))))
  217.        (define-vop (,(symbolicate 'data-vector-set/ type))
  218.      (:note "inline array store")
  219.      (:translate data-vector-set)
  220.      (:policy :fast-safe)
  221.      (:args (object :scs (descriptor-reg))
  222.         (index :scs (unsigned-reg) :target shift)
  223.         (value :scs (unsigned-reg zero immediate) :target result))
  224.      (:arg-types ,type positive-fixnum positive-fixnum)
  225.      (:results (result :scs (unsigned-reg)))
  226.      (:result-types positive-fixnum)
  227.      (:temporary (:scs (interior-reg)) lip)
  228.      (:temporary (:scs (non-descriptor-reg)) temp old)
  229.      (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) shift)
  230.      (:generator 25
  231.        (inst srl temp index ,bit-shift)
  232.        (inst sll temp 2)
  233.        (inst addu lip object temp)
  234.        (inst lw old lip
  235.          (- (* vm:vector-data-offset vm:word-bytes)
  236.             vm:other-pointer-type))
  237.        (inst and shift index ,(1- elements-per-word))
  238.        ,@(when (eq (backend-byte-order *backend*) :big-endian)
  239.            `((inst xor shift ,(1- elements-per-word))))
  240.        ,@(unless (= bits 1)
  241.            `((inst sll shift ,(1- (integer-length bits)))))
  242.        (unless (and (sc-is value immediate)
  243.             (= (tn-value value) ,(1- (ash 1 bits))))
  244.          (inst li temp ,(1- (ash 1 bits)))
  245.          (inst sll temp shift)
  246.          (inst nor temp temp zero-tn)
  247.          (inst and old temp))
  248.        (unless (sc-is value zero)
  249.          (sc-case value
  250.            (immediate
  251.         (inst li temp (logand (tn-value value) ,(1- (ash 1 bits)))))
  252.            (unsigned-reg
  253.         (inst and temp value ,(1- (ash 1 bits)))))
  254.          (inst sll temp shift)
  255.          (inst or old temp))
  256.        (inst sw old lip
  257.          (- (* vm:vector-data-offset vm:word-bytes)
  258.             vm:other-pointer-type))
  259.        (sc-case value
  260.          (immediate
  261.           (inst li result (tn-value value)))
  262.          (zero
  263.           (move result zero-tn))
  264.          (unsigned-reg
  265.           (move result value)))))
  266.        (define-vop (,(symbolicate 'data-vector-set-c/ type))
  267.      (:translate data-vector-set)
  268.      (:policy :fast-safe)
  269.      (:args (object :scs (descriptor-reg))
  270.         (value :scs (unsigned-reg zero immediate) :target result))
  271.      (:arg-types ,type
  272.              (:constant
  273.               (integer 0
  274.                    ,(1- (* (1+ (- (floor (+ #x7fff
  275.                             vm:other-pointer-type)
  276.                              vm:word-bytes)
  277.                           vm:vector-data-offset))
  278.                        elements-per-word))))
  279.              positive-fixnum)
  280.      (:info index)
  281.      (:results (result :scs (unsigned-reg)))
  282.      (:result-types positive-fixnum)
  283.      (:temporary (:scs (non-descriptor-reg)) temp old)
  284.      (:generator 20
  285.        (multiple-value-bind (word extra) (floor index ,elements-per-word)
  286.          ,@(when (eq (backend-byte-order *backend*) :big-endian)
  287.          `((setf extra (logxor extra (1- ,elements-per-word)))))
  288.          (inst lw old object
  289.            (- (* (+ word vm:vector-data-offset) vm:word-bytes)
  290.               vm:other-pointer-type))
  291.          (unless (and (sc-is value immediate)
  292.               (= (tn-value value) ,(1- (ash 1 bits))))
  293.            (cond ((= extra ,(1- elements-per-word))
  294.               (inst sll old ,bits)
  295.               (inst srl old ,bits))
  296.              (t
  297.               (inst li temp
  298.                 (lognot (ash ,(1- (ash 1 bits)) (* extra ,bits))))
  299.               (inst and old temp))))
  300.          (sc-case value
  301.            (zero)
  302.            (immediate
  303.         (let ((value (ash (logand (tn-value value) ,(1- (ash 1 bits)))
  304.                   (* extra ,bits))))
  305.           (cond ((< value #x10000)
  306.              (inst or old value))
  307.             (t
  308.              (inst li temp value)
  309.              (inst or old temp)))))
  310.            (unsigned-reg
  311.         (inst sll temp value (* extra ,bits))
  312.         (inst or old temp)))
  313.          (inst sw old object
  314.            (- (* (+ word vm:vector-data-offset) vm:word-bytes)
  315.               vm:other-pointer-type))
  316.          (sc-case value
  317.            (immediate
  318.         (inst li result (tn-value value)))
  319.            (zero
  320.         (move result zero-tn))
  321.            (unsigned-reg
  322.         (move result value)))))))))
  323.  
  324. (def-small-data-vector-frobs simple-bit-vector 1)
  325. (def-small-data-vector-frobs simple-array-unsigned-byte-2 2)
  326. (def-small-data-vector-frobs simple-array-unsigned-byte-4 4)
  327.  
  328.  
  329. ;;; And the float variants.
  330. ;;; 
  331.  
  332. (define-vop (data-vector-ref/simple-array-single-float)
  333.   (:note "inline array access")
  334.   (:translate data-vector-ref)
  335.   (:policy :fast-safe)
  336.   (:args (object :scs (descriptor-reg))
  337.      (index :scs (any-reg)))
  338.   (:arg-types simple-array-single-float positive-fixnum)
  339.   (:results (value :scs (single-reg)))
  340.   (:result-types single-float)
  341.   (:temporary (:scs (interior-reg)) lip)
  342.   (:generator 20
  343.     (inst addu lip object index)
  344.     (inst lwc1 value lip
  345.       (- (* vm:vector-data-offset vm:word-bytes)
  346.          vm:other-pointer-type))
  347.     (inst nop)))
  348.  
  349. (define-vop (data-vector-set/simple-array-single-float)
  350.   (:note "inline array store")
  351.   (:translate data-vector-set)
  352.   (:policy :fast-safe)
  353.   (:args (object :scs (descriptor-reg))
  354.      (index :scs (any-reg))
  355.      (value :scs (single-reg) :target result))
  356.   (:arg-types simple-array-single-float positive-fixnum single-float)
  357.   (:results (result :scs (single-reg)))
  358.   (:result-types single-float)
  359.   (:temporary (:scs (interior-reg)) lip)
  360.   (:generator 20
  361.     (inst addu lip object index)
  362.     (inst swc1 value lip
  363.       (- (* vm:vector-data-offset vm:word-bytes)
  364.          vm:other-pointer-type))
  365.     (unless (location= result value)
  366.       (inst move :single result value))))
  367.  
  368. (define-vop (data-vector-ref/simple-array-double-float)
  369.   (:note "inline array access")
  370.   (:translate data-vector-ref)
  371.   (:policy :fast-safe)
  372.   (:args (object :scs (descriptor-reg))
  373.      (index :scs (any-reg)))
  374.   (:arg-types simple-array-double-float positive-fixnum)
  375.   (:results (value :scs (double-reg)))
  376.   (:result-types double-float)
  377.   (:temporary (:scs (interior-reg)) lip)
  378.   (:generator 20
  379.     (inst addu lip object index)
  380.     (inst addu lip index)
  381.     (inst lwc1 value lip
  382.       (- (* vm:vector-data-offset vm:word-bytes)
  383.          vm:other-pointer-type))
  384.     (inst lwc1-odd value lip
  385.       (+ (- (* vm:vector-data-offset vm:word-bytes)
  386.         vm:other-pointer-type)
  387.          vm:word-bytes))
  388.     (inst nop)))
  389.  
  390. (define-vop (data-vector-set/simple-array-double-float)
  391.   (:note "inline array store")
  392.   (:translate data-vector-set)
  393.   (:policy :fast-safe)
  394.   (:args (object :scs (descriptor-reg))
  395.      (index :scs (any-reg))
  396.      (value :scs (double-reg) :target result))
  397.   (:arg-types simple-array-double-float positive-fixnum double-float)
  398.   (:results (result :scs (double-reg)))
  399.   (:result-types double-float)
  400.   (:temporary (:scs (interior-reg)) lip)
  401.   (:generator 20
  402.     (inst addu lip object index)
  403.     (inst addu lip index)
  404.     (inst swc1 value lip
  405.       (- (* vm:vector-data-offset vm:word-bytes)
  406.          vm:other-pointer-type))
  407.     (inst swc1-odd value lip
  408.       (+ (- (* vm:vector-data-offset vm:word-bytes)
  409.         vm:other-pointer-type)
  410.          vm:word-bytes))
  411.     (unless (location= result value)
  412.       (inst move :double result value))))
  413.  
  414.  
  415.  
  416. ;;; These vops are useful for accessing the bits of a vector irrespective of
  417. ;;; what type of vector it is.
  418. ;;; 
  419.  
  420. (define-vop (raw-bits word-index-ref)
  421.   (:note "raw-bits VOP")
  422.   (:translate %raw-bits)
  423.   (:results (value :scs (unsigned-reg)))
  424.   (:result-types unsigned-num)
  425.   (:variant 0 vm:other-pointer-type))
  426.  
  427. (define-vop (set-raw-bits word-index-set)
  428.   (:note "setf raw-bits VOP")
  429.   (:translate %set-raw-bits)
  430.   (:args (object :scs (descriptor-reg))
  431.      (index :scs (any-reg zero immediate unsigned-immediate))
  432.      (value :scs (unsigned-reg)))
  433.   (:arg-types * positive-fixnum unsigned-num)
  434.   (:results (result :scs (unsigned-reg)))
  435.   (:result-types unsigned-num)
  436.   (:variant 0 vm:other-pointer-type))
  437.  
  438.  
  439.  
  440.  
  441. ;;;; Misc. Array VOPs.
  442.  
  443.  
  444. #+nil
  445. (define-vop (vector-word-length)
  446.   (:args (vec :scs (descriptor-reg)))
  447.   (:results (res :scs (any-reg descriptor-reg)))
  448.   (:generator 6
  449.     (loadw res vec clc::g-vector-header-words)
  450.     (inst niuo res res clc::g-vector-words-mask-16)))
  451.  
  452. (define-vop (get-vector-subtype get-header-data))
  453. (define-vop (set-vector-subtype set-header-data))
  454.  
  455.